
#include "../inc/mos_string.h"


/*计算分隔符数量 */
S32 str_stoken_count(const SPTR src, const SPTR delim)
{   
    if(NULL == src || NULL == delim)
    {       
        return SERR;    
    }
    
    const SPTR str = src;    
    S32 len = strlen(delim);    
    S32 num = 0;    
    while(str)  
    {       
        str = strstr(str, delim);     
        if(str)     
        {           
            str += len;         
            num++;      
        }   
    }   
    return num;
}

/* 按照分隔符切割字符串  */
SPPTR str_stoken(const SPTR src, const SPTR delim)
{    
    if(NULL == src || NULL == delim)
    {       
        return NULL;    
    }
    
    S32 num = str_stoken_count(src, delim); 
    S32 delim_len = strlen(delim);  
    SPPTR str = NULL;  
    if(num <= 0)    
    {       
        return NULL;    
    }       
    if(strncmp(src, delim, delim_len) 
        && strncmp(src + strlen(src) - delim_len, delim, delim_len))  
    {      
        num += 2;   
    }   
    else    
    {       
        num += 1;   
    }   

    str = (SPPTR)calloc(num , sizeof(SPTR));  
    const SPTR str_head = src;   
    const SPTR pstr = src; 
    S32 slen = 0;  
    S32 i = 0;  

    while(i < num)  
    {       
        pstr = strstr(pstr, delim);    
        if(pstr == NULL)        
        {           
            if(*str_head != '\0')           
            {
                str[i] = (SPTR)calloc(1, strlen(str_head) + 1); 
                memcpy(str[i], str_head, strlen(str_head));            
            }
            else            
            {               
                str[i] = NULL;        
            }           
            break;      
        }       
        else        
        {           
            slen = pstr - str_head;         
            if(slen == 0)           
            {               
                pstr += delim_len;  
                str_head = pstr;            
                continue;          
            }           
            str[i] = (SPTR)calloc(1,slen + 1); 
            strncpy(str[i], str_head, slen);           
            i++;        
        }
        
        pstr += delim_len;      
        str_head = pstr;    
    }  
    return str;
}

/* 释放切割字符串内存和  str_stoken 配套函数*/
Void str_stoken_free(SPPTR p)
{   
    if(p == NULL)       
        return; 
    SPPTR q = p;   
    while(*q != NULL)    
    {       
        free(*q);       
        q++;    
    }   
    free(p);
}

/* 判断字符串是不是数字串 */
BOOL str_isdigit(const SPTR str)
{
    const SPTR tp = str;
    while(*tp != '\0')
    {
        if(*tp - 48 > 9 || *tp - 48 < 0) //'0' = 48
        {
            return FALSE;
        }
    }

    return TRUE;
}

/* 去掉字符串前空白 

新非空白其实地址 (SPTR)&src[len]

*/
S32 str_begain_trim(SPTR src) 
{           
    S32 len = 0;   
    SPTR p = src;     
    while((' ' == *p)      //空字符
        || ('\t' == *p)    //tab字符
        || ('\n' == *p)    //换
        || ('\r' == *p)    //回车字符
        || ('\f' == *p)    // 换页
        || ('\b' == *p)    //退格
        || ('\a' == *p)    //警告
        || ('\v' == *p)    //垂直跳格
        || ('\0' == *p))   //结束符
        {
            *p = '\0';
            p++;
            len++;
        }


    return len;
}

/* 去掉字符串末尾空白，不包括 \0 */
Void str_end_trim(SPTR str, S32 len)
{
    SPTR p = (SPTR)&str[len];
    while((' ' == *p)      //空字符
        || ('\t' == *p)    //tab字符
        || ('\n' == *p)    //换
        || ('\r' == *p)    //回车字符
        || ('\f' == *p)    // 换页
        || ('\b' == *p)    //退格
        || ('\a' == *p)    //警告
        || ('\v' == *p)    //垂直跳格
        || ('\0' == *p))   //结束符
        *p-- = '\0';
}


//=========超级字符串=======SString============================


/*
    将按照@str 的数据初始化一个SString, 分配内存
    为strlen(@str) + 2, 再将@str数据拷贝进去
*/
SString *sstring_new(const SPTR str)                                 
{
    U32 len = 0;
    if(NULL == str ||(strlen(str)) == 0)
    {
        len = 0;
    }
    else
    {   
        len = strlen(str);
    }
    
    SString *s = NULL;
    s = (SString *)calloc(1, sizeof(SString));        
    if (NULL == s)
    {
        return NULL;                                      
    }
    
    s->str = calloc(1, len);
    if(NULL == s->str)
    {
        free(s);
        return NULL;                                      
    }
    
    strncpy(s->str, str, len);
    s->mSize = len;
    s->sLen = len;
    return s;
}

/*
    将按照给定的大小@len 初始化一个SString
    初始值为空
*/

SString *sstring_new_sized(const U32 len)
{
    SString *ss = NULL;
    ss = (SString *)calloc(1, sizeof(SString));        
    if (NULL == ss)
    {
        return NULL;                                      
    }

    if(len != 0)
    {
        ss->str   = (SPTR)calloc(1,len);
        if(NULL == ss->str)
        {
            free(ss);
            return NULL;                                      
        }
        ss->mSize  = len;
        ss->sLen   = len;
    }

    return ss;
}

/*
    @ss 不能为NULL
    @amt 还要增加的长度


*/
S32 sstring_realloc(SString *ss, U32 amt)                          
{
    if(NULL == ss)
    {
        DEBUG("ss is null!");
        return SERR;
    }

    SPTR ptr = NULL;
    ptr = (SPTR)realloc(ss->str, ss->mSize + amt);
    if(ptr != NULL)
    {
        ss->str = ptr;
        ss->mSize += amt;
    }
    else
    {
        DEBUG("realloc is failed!");
        return SERR;
    }


    return OK;
}

/* 释放内存 */
Void sstring_free(SString *ss)                                 
{ 
    if(ss == NULL)
    {
        return;
    }
    
    if(ss->str != NULL)
    {
        free(ss->str);                     
    }

    free(ss); 
}

/*
    只能清除已分配空间的指针，
    对象清空请用memset
*/
Void sstring_clear(SString *ss)                             
{   
    if(NULL != ss)
    {
        if(ss->str != NULL)
        {
            memset(ss->str, 0x0, ss->mSize);
            ss->sLen = 0;
        }

    }
}

/*
    将@src 中@len 长度数据拷贝到@dst 中
    如果@dst 

*/
S32 sstring_scpy(SString *dst, const SPTR src, U32 len)                        
{
    if(NULL == dst || NULL == dst->str || NULL == src)
    {
        return SERR;
    }

    if(dst->mSize > len)
    {
        strncpy(dst->str, src, len);
        dst->sLen = len;
    }
    else
    {
        if(sstring_realloc(dst, len+1) == OK)
        {
            strncpy(dst->str, src, len);
            dst->sLen = len;
        }
        else
        {
            return SERR;
        }

    }

    dst->str[len] = '\0';
    return OK;
}
/* 内存拷贝 */
S32 sstring_mcpy(SString *ss, const SPTR str, U32 len)                                 
{   
    if(NULL == ss || NULL == str)
    {
        return SERR;
    }

    if(len >= ss->mSize)
    {
        SPTR ptr = NULL;
        ptr = (SPTR)calloc(1, len);
        if(ptr != NULL)
        {
            memcpy(ptr, str, len);
            free(ss->str);
            ss->str = ptr;
            ss->mSize = len;
        }        
    }
    else
    {
        memcpy(ss->str, str, len);
    }
    
    ss->sLen = len;
    ss->str[len] = '\0';
    return OK;

}
/* 追加内容 */
S32 sstring_append(SString *dst, const SPTR str, U32 len)                      
{
    if(NULL == dst || NULL == str)
    {
        return SERR;
    }
    
    if(NULL == dst->str)
    {
        return SERR;
    }
    
    if(len < dst->mSize - dst->sLen)
    {
        strncpy(&dst->str[dst->sLen], str, len);
    }
    else
    {
        if(sstring_realloc(dst, len) == OK)
        {
            strncpy(&dst->str[dst->sLen], str, len);
        }
        else
        {
            return SERR;
        }
    }
    
    dst->sLen += len;                                      
    dst->str[dst->sLen] = '\0';
    
    return OK;
}

/* 追加格式化内容 */
Void sstring_append_format(SString *ss, const char *fmt, ...) 
{
    if(ss == NULL)
    {
        return;
    }

    SPTR pBuf = NULL;
    S32 result = 0;
    /* lint -e530 */
    va_list ap;
    va_start(ap, fmt);
    result = vasprintf (&pBuf, fmt, ap);
    va_end(ap);
    /* lint +e530 */
    
    if (NULL == pBuf)
    {
      return;
    }
    if (result < 0)
    {
        free(pBuf);
        return;
    }

    sstring_append(ss, pBuf, result);
    free(pBuf);

}

/* 存入格式化内容 */
Void sstring_format(SString *ss, const char *fmt, ...) 
{
    if(ss == NULL)
    {
         return;
    }

    SPTR pBuf = NULL;
    S32 result = 0;
    /* lint -e530 */
    va_list ap;
    va_start(ap, fmt);
    result = vasprintf (&pBuf, fmt, ap);
    va_end(ap);
    /* lint +e530 */
    
    if (NULL == pBuf)
    {
      return;
    }
    if (result < 0)
    {
        free(pBuf);
        return;
    }
    if(ss->str)
        free(ss->str);
    
    ss->str = pBuf;
    ss->sLen = result;
    ss->mSize = result + 1;
}

